home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 317_01 / g3sencod.c < prev    next >
C/C++ Source or Header  |  1990-06-16  |  9KB  |  267 lines

  1. /*    $Id: g3sencod.c 1.2 90/06/09 18:22:52 marking Exp $
  2.  *
  3.  NAME
  4.  *    g3sencod.c -- encode group 3 data using nested if statements
  5.  *
  6.  TYPE
  7.  *    C procedures
  8.  *
  9.  SYNOPSIS
  10.  *    char    g3j_initialize (short image_width, short image_length);
  11.  *    char    g3j_encode_new_row (void);
  12.  *    char    g3j_encode_pad (char pad_type);
  13.  *    char    g3j_encode_black (short);
  14.  *    char    g3j_encode_white (short);
  15.  *
  16.  DESCRIPTION
  17.  *    These routines are used to encode group 3 and group 4 images. (The
  18.  *    encoding of group 4 also requires other routines in a separate file.)
  19.  *
  20.  RETURNS
  21.  *
  22.  LEGAL
  23.  *    Copyright 1989, 1990 Michael P. Marking, Post Office Box 8039,
  24.  *    Scottsdale, Arizona 85252-8039. All rights reserved.
  25.  *
  26.  *    License is granted by the copyright holder to distribute and use this
  27.  *    code without payment of royalties or the necessity of notification as
  28.  *    long as this notice (all the text under "LEGAL") is included.
  29.  *
  30.  *    Reference: $Id: g3sencod.c 1.2 90/06/09 18:22:52 marking Exp $
  31.  *
  32.  *    This program is offered without any warranty of any kind. It includes
  33.  *    no warranty of merchantability or fitness for any purpose. Testing and
  34.  *    suitability for any use are the sole responsibility of the user.
  35.  * 
  36.  HISTORY
  37.  *    $Log:    g3sencod.c $
  38.  * Revision 1.2  90/06/09  18:22:52  marking
  39.  * clean up comments for release
  40.  * 
  41.  * Revision 1.1  89/06/30  17:00:00  marking
  42.  * Initial revision
  43.  * 
  44.  *
  45.  NOTES
  46.  *    1.    Encode a pad to the next byte to flush the output buffer.
  47.  *
  48.  PORTABILITY
  49.  *    Tested using Microsoft C 5.1. Some memory models may not work due to
  50.  *    the large encoding arrays.
  51.  *
  52.  *    There is a non-portable use of "global" variables in the file g3g4.h,
  53.  *    about which a minority of compilers will justifiably complain. Certain
  54.  *    variables are declared in g3g4.h without extern keywords. Strictly
  55.  *    speaking, they should be declared extern in all but one module, but
  56.  *    that would require complication of g3g4.h. If it gets past your
  57.  *    compiler and linker, you can probably ignore it.
  58.  *
  59.  SEE ALSO
  60.  *    g4sencod.c -- encode group 4 image using nested if statements
  61.  *
  62.  INFORMATION
  63.  *    Although there is no support offered with this program, the author will
  64.  *    endeavor to correct errors. Updates will also be made available from
  65.  *    time to time.
  66.  *
  67.  *    Contact: Michael P. Marking, Post Office Box 8039, Scottsdale, Arizona
  68.  *    85252-8039 USA. Replies are not guaranteed to be swift. Beginning
  69.  *    July 1990, e-mail may be sent to uunet!ipel!marking.
  70.  *
  71.  *    Also beginning in July 1990, this code will be archived at the
  72.  *    ipel!phoenix BBS in file g3g4.zoo. The 24-hour telephone number
  73.  *    for 300/1200/2400 is (602)274-0462. When logging in, specify user
  74.  *    "public", system "bbs", and password "public".
  75.  *
  76.  *    This code is also available from the C Users Group in volume 317.
  77.  *
  78.  */
  79.  
  80. #include "g3g4.h"
  81.  
  82. static short EOL_code = 0x0010, EOL_length = 12;
  83.  
  84. static short encode_black_code (short);
  85. static short encode_white_code (short);
  86.  
  87. char g3j_initialize (short image_width, short image_length)
  88. {
  89.   initialize_encode ();
  90.   return (0);
  91. }
  92.  
  93. char g3j_encode_new_row (void)
  94. {
  95.   encode_word (EOL_code, EOL_length);
  96.   return (0);
  97. }
  98.  
  99. char g3j_encode_pad (char pad_type)
  100. {
  101.   short bits_to_pad;
  102.   switch (pad_type)
  103.   {
  104.     case PAD_NONE:
  105.       break;
  106.     case PAD_BYTE:
  107.       if (encode_position) /* if not already on a byte boundary */
  108.     encode_word (0, 8 - encode_position);
  109.       break;
  110.     case PAD_NIBBLE:
  111.       bits_to_pad = (8 - encode_position) & 3;
  112.       if (bits_to_pad) encode_word (0, bits_to_pad);
  113.       break;
  114.     case PAD_ODD_NIBBLE:
  115.       if (encode_position > 0 && encode_position < 4)
  116.       {
  117.     bits_to_pad = 4 - encode_position;
  118.     encode_word (0, bits_to_pad);
  119.       }
  120.       else if (encode_position > 4)
  121.       {
  122.     bits_to_pad = 12 - encode_position;
  123.     encode_word (0, bits_to_pad);
  124.       }
  125.       break;
  126.     default:
  127.       break;
  128.   }
  129.   return (0);
  130. }
  131.  
  132. char g3j_encode_black (short runlength)
  133. {
  134.   runlength = encode_black_code (runlength);
  135.   while (runlength) runlength = encode_black_code (runlength);
  136.   return (0);
  137. }
  138.  
  139. static short encode_black_code (short runlength)
  140. {
  141.   static short term_codes [64] =
  142.   {
  143.     0x0DC0, 0x4000, 0xC000, 0x8000, 0x6000, 0x3000,
  144.     0x2000, 0x1800, 0x1400, 0x1000, 0x0800, 0x0A00,
  145.     0x0E00, 0x0400, 0x0700, 0x0C00, 0x05C0, 0x0600,
  146.     0x0200, 0x0CE0, 0x0D00, 0x0D80, 0x06E0, 0x0500,
  147.     0x02E0, 0x0300, 0x0CA0, 0x0CB0, 0x0CC0, 0x0CD0,
  148.     0x0680, 0x0690, 0x06A0, 0x06B0, 0x0D20, 0x0D30,
  149.     0x0D40, 0x0D50, 0x0D60, 0x0D70, 0x06C0, 0x06D0,
  150.     0x0DA0, 0x0DB0, 0x0540, 0x0550, 0x0560, 0x0570,
  151.     0x0640, 0x0650, 0x0520, 0x0530, 0x0240, 0x0370,
  152.     0x0380, 0x0270, 0x0280, 0x0580, 0x0590, 0x02B0,
  153.     0x02C0, 0x05A0, 0x0660, 0x0670
  154.   };
  155.   static short makeup_codes [40] =
  156.   {
  157.     0x03C0, 0x0C80, 0x0C90, 0x05B0, 0x0330, 0x0340,
  158.     0x0350, 0x0360, 0x0368, 0x0250, 0x0258, 0x0260,
  159.     0x0268, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0,
  160.     0x03B8, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02D0,
  161.     0x02D8, 0x0320, 0x0328, 0x0100, 0x0180, 0x01A0,
  162.     0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170,
  163.     0x01C0, 0x01D0, 0x01E0, 0x01F0
  164.   };
  165.   static short term_lengths [64] =
  166.   {
  167.     10, 3, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 9, 10, 10,
  168.     10, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
  169.     12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
  170.     12, 12, 12, 12, 12, 12, 12, 12, 12, 12
  171.   };
  172.   static short makeup_lengths [40] =
  173.   {
  174.     10, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
  175.     13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 11, 11, 12, 12, 12, 12, 12, 12,
  176.     12, 12, 12, 12
  177.   };
  178.   short remaining;
  179.   if (runlength < 64)
  180.   {
  181.     encode_word (term_codes [runlength], term_lengths [runlength]);
  182.     return (0);
  183.   }
  184.   else if (runlength < 2561)
  185.   {
  186.     short x;
  187.     x = (runlength - 64) / 64;
  188.     encode_word (makeup_codes [x], makeup_lengths [x]);
  189.     remaining = runlength - (64 * (1 + x));
  190.     if (!remaining) encode_word (term_codes [0], term_lengths [0]);
  191.     return (remaining);
  192.   }
  193.   else
  194.   {
  195.     encode_word (makeup_codes [39], makeup_lengths [39]);
  196.     return (runlength - 2560);
  197.   }
  198. }
  199.  
  200. char g3j_encode_white (short runlength)
  201. {
  202.   runlength = encode_white_code (runlength);
  203.   while (runlength) runlength = encode_white_code (runlength);
  204.   return (0);
  205. }
  206.  
  207. static short encode_white_code (short runlength)
  208. {
  209.   static short term_codes [64] =
  210.   {
  211.     0x3500, 0x1c00, 0x7000, 0x8000, 0xb000, 0xc000,
  212.     0xe000, 0xf000, 0x9800, 0xa000, 0x3800, 0x4000,
  213.     0x2000, 0x0c00, 0xd000, 0xd400, 0xa800, 0xac00,
  214.     0x4e00, 0x1800, 0x1000, 0x2e00, 0x0600, 0x0800,
  215.     0x5000, 0x5600, 0x2600, 0x4800, 0x3000, 0x0200,
  216.     0x0300, 0x1a00, 0x1b00, 0x1200, 0x1300, 0x1400,
  217.     0x1500, 0x1600, 0x1700, 0x2800, 0x2900, 0x2a00,
  218.     0x2b00, 0x2c00, 0x2d00, 0x0400, 0x0500, 0x0a00,
  219.     0x0b00, 0x5200, 0x5300, 0x5400, 0x5500, 0x2400,
  220.     0x2500, 0x5800, 0x5900, 0x5a00, 0x5b00, 0x4a00,
  221.     0x4b00, 0x3200, 0x3300, 0x3400
  222.   };
  223.   static short makeup_codes [40] =
  224.   {
  225.     0xd800, 0x9000, 0x5c00, 0x6e00, 0x3600, 0x3700,
  226.     0x6400, 0x6500, 0x6800, 0x6700, 0x6600, 0x6680,
  227.     0x6900, 0x6980, 0x6a00, 0x6a80, 0x6b00, 0x6b80,
  228.     0x6c00, 0x6c80, 0x6d00, 0x6d80, 0x4c00, 0x4c80,
  229.     0x4d00, 0x6000, 0x4d80, 0x0100, 0x0180, 0x01a0,
  230.     0x0120, 0x0130, 0x0140, 0x0150, 0x0160, 0x0170,
  231.     0x01c0, 0x01d0, 0x01e0, 0x01f0
  232.   };
  233.   static short term_lengths [64] =
  234.   {
  235.     8, 6, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
  236.     7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  237.     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
  238.   };
  239.   static short makeup_lengths [40] =
  240.   {
  241.     5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
  242.     9, 6, 9, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
  243.   };
  244.   short remaining;
  245.   if (runlength < 64)
  246.   {
  247.     encode_word (term_codes [runlength], term_lengths [runlength]);
  248.     return (0);
  249.   }
  250.   else if (runlength < 2561)
  251.   {
  252.     short x;
  253.     x = (runlength - 64) / 64;
  254.     encode_word (makeup_cod